package com.osdp.auth.server.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.osdp.auth.server.ITokenService;
import com.osdp.auth.server.ILoginService;
import com.osdp.auth.server.IUserService;
import com.osdp.common.constant.CommonConstant;
import com.osdp.common.exception.PlatformException;
import com.osdp.common.util.MessageUtil;
import com.osdp.common.util.PasswordUtil;
import com.osdp.common.base.JWTInfo;
import com.osdp.common.util.RSAUtil;
import com.osdp.sc.dto.TenantUserDTO;
import com.osdp.uc.dto.UserDTO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 *    工具名称	       执行1000次耗时	10000次	   100000次	1000000次
Apache BeanUtils	    390ms	    854ms	    1763ms	    8408ms
Apache PropertyUtils	26ms	    221ms	    352ms	    2663ms
spring BeanUtils	    39ms	    315ms	    373ms	    949ms
Cglib BeanCopier	    64ms	    144ms	    171ms	    309ms

 * @author liubo
 *
 */
@Slf4j
@Service
//@Transactional
public class LoginServiceImpl implements ILoginService {

    @Autowired
    private ITokenService tokenService;

    @Autowired
    private IUserService userService;


    @Value("${tenant.base.tenantId}")
    private String defaultTenantId;

    /**
     * 验证用户是否存大，密码是否正确
     * @param username
     * @param password
     * @return
     */
    private UserDTO verifyUser(String username, String password) {
        if (StringUtils.isEmpty(username)) {
            throw new PlatformException(MessageUtil.getMessage(10001,"username"));
        }
        if (StringUtils.isEmpty(password)) {
            throw new PlatformException(MessageUtil.getMessage(10001,"password"));
        }
        UserDTO user = queryUserByUserName(username);
        if(user == null){
            throw new PlatformException(MessageUtil.getMessage(10010,"username"));
        }
        //用户输入密码
        String userPwd = PasswordUtil.encrypt(username, password, user.getSalt());
        //数据库存储密码
        String sysPwd = user.getPassWord();
        if (!StringUtils.equals(userPwd, sysPwd)) {
            throw new PlatformException(MessageUtil.getMessage(10004));
        }
        return user;
    }

    @Override
    public String login(String username, String password) {
        return loginWithTenant(username, password, null,true);
    }

    @Override
    public String loginWithTenant(String username, String password, String tenantCode, boolean verify) {
        UserDTO user = null;
        if(verify){
            user = verifyUser(username, password);
        }else{
            user = queryUserByUserName(username);
        }
        if(null == user){
            throw new PlatformException(MessageUtil.getMessage(10033));
        }
        //增加一层账号状态检查
        if (user.getValidation() != null && user.getValidation().equals(CommonConstant.FLAG_ZERO_0)) {
            throw new PlatformException(MessageUtil.getMessage(10133));
        }
        List<TenantUserDTO> tenantUsers = userService.queryTenantByUserId(user.getId());
        String currentTenantId = defaultTenantId;
        if (!StringUtils.isEmpty(tenantCode)) {
            currentTenantId = userService.getCurrentTenantId(tenantUsers, tenantCode);
        }
        List<String> tenantIds = userService.getTenantIds(tenantUsers);
        JWTInfo info = new JWTInfo(user.getId(), user.getUserName(), false, currentTenantId);
        info.setTenants(tenantIds);
        List<String> roleCodes = userService.getRoleCodeByUserId(user.getId());
        info.setRoles(roleCodes);
        if (hasSuperAdmin(roleCodes)) {
            info.setSuperAdmin(true);
        }
        log.info("info信息：{}", JSONObject.toJSONString(info));
        String token = tokenService.create(info);
        return token;
    }

    @Override
    public String loginWithTenant(String username, String password, String tenantCode) {
        return loginWithTenant(username,password,tenantCode,true);
    }

    @Override
    public String unverifiedLogin(String encryptedAccount) {
        return unverifiedLogin(encryptedAccount,true);
    }

    @Override
    public String unverifiedLogin(String account, boolean encrypted) {
        String username = null;
        String tenant = null;
        if(StringUtils.isEmpty(account)){
            throw new PlatformException(MessageUtil.getMessage(10001,"account"));
        }
        if(encrypted){
            try {
                account = RSAUtil.decrypt(account);
            } catch (Exception e) {
                if(log.isErrorEnabled()){
                    log.error(e.getMessage(), e);
                }
                throw new PlatformException(MessageUtil.getMessage(10032));
            }
        }
        if (account.contains("#")) {
            String[] userNameWithTenantCode = StringUtils.split(account,"#");
            if (userNameWithTenantCode.length < 2) {
                if(log.isErrorEnabled()){
                    log.error("用户信息未携带租户信息");
                }
                return null;
            }
            tenant = userNameWithTenantCode[1];
            username = userNameWithTenantCode[0];
        }else{
            username = account;
        }
        return loginWithTenant(username,null,tenant,false);
    }

    @Override
    public boolean loginOut(String token) {
        return tokenService.invalid(token);
    }

    @Override
    public UserDTO queryUserByUserName(String userName){
        return userService.queryUserByUserName(userName);
    }


    /**
     * 判断当前用户是否有超级管理员权限
     *
     * @return
     */
    private boolean hasSuperAdmin(List<String> roleCodes) {
        if (CollectionUtils.isEmpty(roleCodes)) {
            return false;
        }
        return roleCodes.contains(CommonConstant.SUPER_TENANT_ADMIN);
    }



}
